/*-----------------------------------------------------------------------
								 \\\|///
							   \\  - -  //
								(  @ @  )  
+-----------------------------oOOo-(_)-oOOo-----------------------------+
CONFIDENTIAL IN CONFIDENCE
This confidential and proprietary software may be only used as authorized
by a licensing agreement from CrazyBingo (Thereturnofbingo).
In the event of publication, the following notice is applicable:
Copyright (C) 2012-20xx CrazyBingo Corporation
The entire notice above must be reproduced on all authorized copies.
Author				:		CrazyBingo
Technology blogs 	: 		http://blog.chinaaet.com/crazybingo
Email Address 		: 		thereturnofbingo@gmail.com
Filename			:		PC2FPGA_UART_TB.v
Data				:		2013-11-04
Description			:		Test UART Communication between PC and FPGA.
Modification History	:
Data			By			Version			Change Description
=========================================================================
13/11/04		CrazyBingo	1.0				Original

-------------------------------------------------------------------------
|                                     Oooo								|
+-------------------------------oooO--(   )-----------------------------+
                               (   )   ) /
                                \ (   (_/
                                 \_)
-----------------------------------------------------------------------*/   

`timescale 1ns/1ns
module PC2FPGA_UART_TB;


//------------------------------------------
//clock generate module
reg	clk;  
reg	rst_n;
parameter PERIOD = 10;	//100MHz
initial	
begin
	clk = 0;
	forever	#(PERIOD/2)	
	clk = ~clk;
end

task task_reset;
begin
	rst_n = 0;
	repeat(2) @(negedge clk);
	rst_n = 1;
end
endtask
wire	clk_ref = clk;
wire	sys_rst_n = rst_n;

//------------------------------------
//uart interface
reg				fpga_rxd;
wire			fpga_txd;


//------------------------------------
//Precise clk divider
wire	divide_clken;
precise_divider	
#(
	//DEVIDE_CNT = 42.94967296 * fo
	
//	.DEVIDE_CNT	(32'd175921860)	//256000bps * 16	
//	.DEVIDE_CNT	(32'd87960930)	//128000bps * 16
//	.DEVIDE_CNT	(32'd79164837)	//115200bps * 16
	.DEVIDE_CNT	(32'd6597070)	//9600bps * 16
)
u_precise_divider
(
	//global
	.clk				(clk_ref),		//100MHz clock
	.rst_n				(sys_rst_n),    //global reset
	
	//user interface
	.divide_clk			(),
	.divide_clken		(divide_clken)
);


wire	clken_16bps = divide_clken;
//---------------------------------
//Data receive for PC to FPGA.
wire			rxd_flag;
wire	[7:0]	rxd_data;
uart_receiver	u_uart_receiver
(
	//gobal clock
	.clk			(clk_ref),
	.rst_n			(sys_rst_n),
	
	//uart interface
	.clken_16bps	(clken_16bps),	//clk_bps * 16
	.rxd			(fpga_rxd),		//uart txd interface
	
	//user interface
	.rxd_data		(rxd_data),		//uart data receive
	.rxd_flag		(rxd_flag)  	//uart data receive done
);

//---------------------------------
//Data receive for PC to FPGA.
uart_transfer	u_uart_transfer
(
	//gobal clock
	.clk			(clk_ref),
	.rst_n			(sys_rst_n),
	
	//uaer interface
	.clken_16bps	(clken_16bps),	//clk_bps * 16
	.txd			(fpga_txd),  	//uart txd interface
           
	//user interface   
	.txd_en			(rxd_flag),		//uart data transfer enable
	.txd_data		(rxd_data), 	//uart transfer data	
	.txd_flag		() 			//uart data transfer done
);



//------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------
//Precise clk divider:9600bps
//------------------------------------
//Precise clk divider
wire	divide_clken2;
precise_divider	
#(
	//DEVIDE_CNT = 42.94967296 * fo
	.DEVIDE_CNT	(32'd412317)	//9600bps
)
u_precise_divider2
(
	//global
	.clk				(clk_ref),		//100MHz clock
	.rst_n				(sys_rst_n),    //global reset
	
	//user interface
	.divide_clk			(),
	.divide_clken		(divide_clken2)
);


//uart data txd simulate
wire	uart_bps_en = 	divide_clken2;
task 	task_uart_txd;
input	[7:0]	uart_data;
begin
	//8'hCB = 8'b1100_1011	
	@(posedge uart_bps_en);  fpga_rxd = 0;	//Start
	@(posedge uart_bps_en);  fpga_rxd = uart_data[0];
	@(posedge uart_bps_en);  fpga_rxd = uart_data[1];
	@(posedge uart_bps_en);  fpga_rxd = uart_data[2];
	@(posedge uart_bps_en);  fpga_rxd = uart_data[3];
	@(posedge uart_bps_en);  fpga_rxd = uart_data[4];
	@(posedge uart_bps_en);  fpga_rxd = uart_data[5];
	@(posedge uart_bps_en);  fpga_rxd = uart_data[6];
	@(posedge uart_bps_en);  fpga_rxd = uart_data[7];
	@(posedge uart_bps_en);  fpga_rxd = 1;	//End
	#78;
end
endtask


//---------------------------------------------
//system initialization
task task_sysinit;
begin
	fpga_rxd = 1;
end
endtask

//---------------------------------------
//testbench of the RTL
initial
begin
	task_sysinit;
	task_reset;
	
	#12345;	
	task_uart_txd(8'hCB);
	
	#12345;		
	task_uart_txd(8'h0A);
	
	#12345;		
	task_uart_txd(8'h09);
	
	#12345;		
	task_uart_txd(8'h0F);	

end

endmodule

